package com.nulldev.util.web.YouTubeExtractor.comments.handlers;

import static com.nulldev.util.web.YouTubeExtractor.comments.handlers.Util.isVerified;

import java.util.List;

import com.nulldev.util.JVM.Arguments;
import com.nulldev.util.VariableAPI.MathUtil;
import com.nulldev.util.VariableAPI.StringsUtil;
import com.nulldev.util.languages.json.uniapi.UniJsonIterableValue;
import com.nulldev.util.languages.json.uniapi.UniJsonValue;
import com.nulldev.util.logging.Logger;
import com.nulldev.util.logging.LoggerFactory;
import com.nulldev.util.web.YouTubeExtractor.comments.YTComment;
import com.nulldev.util.web.YouTubeExtractor.comments.YTComments.YouTubeCommentResult;
import com.nulldev.util.web.YouTubeExtractor.util.YouTubeAmountFormatter;

public class MobileContextCommentHandler {

	private static final Logger logger = LoggerFactory.getLoggerD(Arguments.hasArgument("--debug", "--YTComments.debug", "--trace"));

	public static YouTubeCommentResult __process_mobile_context_comments(final String resp, final List<YTComment> comments) {
		final UniJsonValue obj = UniJsonValue.parse(resp);
		final UniJsonValue frameworkUpdates = obj.get("frameworkUpdates");
		if (frameworkUpdates == null || frameworkUpdates.isNull()) {
			logger.warn("resp: " + resp);
			throw new UnsupportedOperationException("Failed to get comments, MISSING_FRAMEWORK_UPDATES!");
		}
		final UniJsonValue entityBatchUpdate = frameworkUpdates.get("entityBatchUpdate");
		final UniJsonIterableValue mutations = entityBatchUpdate.get("mutations").asArray();
		for (int index = 0; index < mutations.size(); index++) {
			final UniJsonValue object = mutations.get(index);
			try {
				if (object.contains("type") && object.getString("type", "").equalsIgnoreCase("ENTITY_MUTATION_TYPE_REPLACE")) {
					final UniJsonValue payload = object.get("payload");
					if (payload.contains("commentEntityPayload")) {
						final UniJsonValue commentEntityPayload = payload.get("commentEntityPayload");
						UniJsonValue next;
						try {
							next = mutations.get(index + 5);
						} catch (Exception e) {
							next = null;
						}
						final String authorName = commentEntityPayload.get("author").getString("displayName");
						final String authorThumbnailUrl = commentEntityPayload.get("author").getString("avatarThumbnailUrl");
						final boolean isLikedByAuthor = false;
						final boolean hasCreatorHeart = false;
						final boolean isPinned = next != null && next.contains("payload") && next.get("payload").contains("commentPinnedStateEntityPayload")
								&& next.get("payload").get("commentPinnedStateEntityPayload").bool("isPinned", false);
						final String comment = commentEntityPayload.get("properties").get("content").getString("content");
						final String comment_cont = null;
						long likes = 0;
						final String fp = commentEntityPayload.get("toolbar").getString("likeCountLiked");
						if (StringsUtil.isNumber(fp)) {
							likes = MathUtil.safeParseL(fp, 0);
						} else
							likes = YouTubeAmountFormatter.format(fp);
						final long replyCount = MathUtil.safeParseL(commentEntityPayload.get("toolbar").getString("replyCount"), -1);
						;
						comments.add(new YTComment(authorName, authorThumbnailUrl, isLikedByAuthor, hasCreatorHeart, isPinned, comment, comment_cont, likes,
								replyCount, isVerified(commentEntityPayload)));
					} else
						continue;
				} else
					continue;
			} catch (Exception ex) {
				logger.error("Failed to add comment!", ex);
				logger.error("Object: " + object);
			}
		}
		String continuation;
		try {
			continuation = obj.get("continuationContents").get("itemSectionContinuation").get("continuations").first().get("nextContinuationData")
					.getString("continuation");
		} catch (Exception e) {
			continuation = null;
		}
		return new YouTubeCommentResult(continuation, comments);
	}
}
